home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / strasm.exe / STRASM.PAS < prev   
Pascal/Delphi Source File  |  1992-01-26  |  4KB  |  109 lines

  1. { ======================================================================
  2.   Here are a couple of handy Turbo Pascal 6.0 assembler routines
  3.   for fast string operations.  Simply include them in your source
  4.   code.  The built-in Turbo Pascal 6.0 assembler takes care of the
  5.   rest.
  6.  
  7.   Author: Keith Greer
  8.           68 Tamworth Rd.
  9.           Troy, OH  45373
  10.  
  11. ========================================================================}
  12.  
  13.  
  14.  
  15. {  SpaceOut removes leading blanks from AnyString and returns the
  16.    resulting string.  For example:
  17.  
  18.    SpaceOut('         My String') = 'My String'
  19.  
  20.    Compared to its comparable pascal version:
  21.  
  22.    ---------------------------------------------------
  23.    function SpaceOut(AnyString : string) : string;
  24.    var
  25.      i,l : integer;
  26.  
  27.    begin
  28.      i:=1; l:=Length(AnyString);
  29.      while (i<l) and (AnyString[i]=' ') do Inc(i);
  30.      if i>l then SpaceOut:='' else
  31.      SpaceOut:=Copy(AnyString,i,l-i+1);
  32.    end;
  33.    ---------------------------------------------------
  34.    this assembler version is over twice as fast, and about 80 bytes
  35.    smaller in generated code size.
  36.  
  37. }
  38.  
  39. function SpaceOut(AnyString:string) :string; assembler;
  40. asm
  41.         PUSH    DS              {Save Data Segment}
  42.         CLD                     {Clear direction flag}
  43.         LES     DI,AnyString    {ES:DI-->AnyString}
  44.         MOV     AL,ES:[DI]      {Get the length of AnyString}
  45.         CBW                     {Make it a word}
  46.         MOV     CX,AX
  47.         JCXZ    @1              {AnyString was ''!}
  48.         INC     DI              {ES:DI-->First char of AnyString}
  49.         MOV     DX,DI           {DX has first char offset}
  50.         ADD     DX,AX           {Add the length}
  51.         MOV     AL,' '          {What to look for}
  52.         REPE    SCASB           {Keep looking till out of spaces or string}
  53.         JE      @1              {Had a string full of spaces, jump}
  54.         DEC     DI              {Move back to the first non-blank}
  55.         MOV     SI,DI           {and put the offset into SI}
  56.         PUSH    ES
  57.         POP     DS              {DS:SI-->First non-blank in AnyString}
  58.         MOV     AX,DX           {AX has offset of last char+1}
  59.         SUB     AX,SI           {minus current offset is length of Result}
  60.         LES     DI,@Result      {ES:DI-->Result}
  61.         STOSB                   {Save the length into Result}
  62.         MOV     CX,AX
  63.         REP     MOVSB           {Get the remainder of AnyString into Result}
  64.         JMP     @2              {All done}
  65. @1:
  66.         LES     DI,@Result
  67.         MOV BYTE PTR ES:[DI],0  {Make Result=''}
  68. @2:                             {Go back}
  69.         POP     DS              {Restore Data Segment}
  70. end;
  71.  
  72. {=======================================================================}
  73.  
  74. { FixLen has a little more practical utility.  It takes AnyString, and
  75.   pads (or truncates) it with any character to length FldSize.  Aside
  76.   from the obvious use of adding blanks to a string to make it a certain
  77.   size, FixLen can also be used to repeat a series characters.  For
  78.   example, to draw a 70-character line using the "=" character:
  79.  
  80.   WriteLn(FixLen('','=',70));
  81.  
  82.   }
  83.  
  84. function FixLen(AnyString:string; PadChar: char; FldSize:word) :string;
  85.                                                              assembler;
  86. asm
  87.         PUSH    DS              {Save Data Segment}
  88.         CLD                     {Clear direction flag}
  89.         LDS     SI,AnyString    {DS:SI-->AnyString}
  90.         LES     DI,@Result      {ES:DI-->String to be returned}
  91.         MOV     BX,DI           {Save DI value for later}
  92.         LODSB                   {AL has Length(AnyString)}
  93.         CBW                     {Make AL into word in AX}
  94.         STOSB                   {Put the length into Result & Inc(DI)}
  95.         MOV     CX,AX           {Length in CX}
  96.         REP     MOVSB           {Pad=AnyString}
  97.         MOV     CX,FldSize      {CX has FldSize}
  98.         XOR     CH,CH           {Make FldSize=FldSize mod 256}
  99.         MOV     ES:[BX],CL      {Make Length(Pad)=FldSize}
  100.         SUB     CX,AX           {CX=FldSize-Length(AnyString)}
  101.         JB      @1              {Return truncated string if CX<0}
  102.         MOV     AL,PadChar      {else load character to pad}
  103.         REP     STOSB           {and pad to FldSize}
  104. @1:                             {Go back}
  105.         POP     DS              {Restore Data Segment}
  106. end;
  107.  
  108.  
  109.